package kaginawa;

import java.util.HashMap;

import netnotifier.NetNotifier;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabFolder2Listener;
import org.eclipse.swt.custom.CTabFolderEvent;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.events.ArmEvent;
import org.eclipse.swt.events.ArmListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.layout.GridLayout;


public class Kaginawa
{
	public static CTabFolder tabFolder=null;
	public static NetNotifier notifier=null;
	public static Display display=null;
	public static HashMap<String,KaginawaMonitor> monitors=new HashMap<String,KaginawaMonitor>();
	
	public static void main(String[] args)
	{
		notifier=new NetNotifier();
		
		// setup display and shell
		display = new Display();
		Shell shell = new Shell(display);
		shell.setText("kaginawa 0.0.0");
		shell.setSize(1000,618);
		shell.setLayout(new GridLayout(1,true));
		
		generateMenu(shell);
		generateTabFolder(shell);
		
		shell.open();
		while (!shell.isDisposed())
		{
			if (!display.readAndDispatch())
			{
				display.sleep();
			}
		}
		notifier.shutdown();
		display.dispose();
		Runtime.getRuntime().exit(0);
	}
	
	private static void generateMenu(final Shell shell)
	{

		// setup menu bar
		Menu menuBar=new Menu(shell,SWT.BAR);
		MenuItem deviceMenuHeader=new MenuItem(menuBar,SWT.CASCADE);
		deviceMenuHeader.setText("device");
		Menu deviceMenu=new Menu(shell,SWT.DROP_DOWN);
		deviceMenuHeader.setMenu(deviceMenu);
		
		MenuItem packetMenuHeader=new MenuItem(menuBar,SWT.CASCADE);
		packetMenuHeader.setText("packets");
		Menu packetMenu=new Menu(shell,SWT.DROP_DOWN);
		packetMenuHeader.setMenu(packetMenu);
	
		MenuItem segmentMenuHeader=new MenuItem(menuBar,SWT.CASCADE);
		segmentMenuHeader.setText("segments");
		Menu segmentMenu=new Menu(shell,SWT.DROP_DOWN);
		segmentMenuHeader.setMenu(segmentMenu);

		MenuItem sessionMenuHeader=new MenuItem(menuBar,SWT.CASCADE);
		sessionMenuHeader.setText("sessions");
		Menu sessionMenu=new Menu(shell,SWT.DROP_DOWN);
		sessionMenuHeader.setMenu(sessionMenu);

		MenuItem pcapMenuHeader=new MenuItem(menuBar,SWT.CASCADE);
		pcapMenuHeader.setText("pcap");
		Menu pcapMenu=new Menu(shell,SWT.DROP_DOWN);
		pcapMenuHeader.setMenu(pcapMenu);
		
		// populate the device menu (make sure this user has access)
		String[] deviceList=null;
		String errorMessage=null;
		try
		{
			deviceList=notifier.getDeviceList();
			if(deviceList.length==0)errorMessage=
				"No accessible devices were found.\nYou may need to escalate privelages.";
		}
		catch(java.lang.UnsatisfiedLinkError e)
		{
			errorMessage="Could not load pcap libraries.\nMake sure pcap is installed.";
		}
			
		if(errorMessage!=null)
		{			
			System.out.println(errorMessage);
			Shell errorShell=new Shell(display);
			errorShell.setText("error");
			Label errorLabel=new Label(errorShell,SWT.NONE);
			errorLabel.setText(errorMessage);
			errorLabel.setAlignment(SWT.CENTER);
			errorLabel.pack();
			errorShell.pack();

			errorShell.open();
			
			while(!errorShell.isDisposed())
			{
				if (!display.readAndDispatch())
				{
					display.sleep();
				}	
			}
			System.exit(0);
		}
		for(String deviceName:notifier.getDeviceList())
		{
			if(deviceName.equals("any"))continue; // ignore the any device on unix systems
			MenuItem menuItem=new MenuItem(deviceMenu,SWT.CHECK);
			menuItem.setText(deviceName);
			menuItem.addListener(SWT.Selection,new Listener()
			{
				public void handleEvent(Event event)
				{
					try
					{
						MenuItem item=(MenuItem)event.widget;
						boolean checked=item.getSelection();
						if(checked)notifier.startSniffer(item.getText());
						else notifier.stopSniffer(item.getText());
					}
					catch(Exception e)
					{
						e.printStackTrace();
					}
				}
			});
		}
		
		MenuItem pcapItem=new MenuItem(deviceMenu,SWT.NONE);
		pcapItem.setText("load pcap");
		pcapItem.addListener(SWT.Selection,new Listener()
		{
			public void handleEvent(Event event)
			{
				FileDialog fileDialog=new FileDialog(shell,SWT.OPEN);
				System.out.println(fileDialog.open());
				System.out.println("pcap yo");
			}
		});
		
		
		Listener notificationMenuListener=new Listener()
		{
			public void handleEvent(Event event)
			{
				MenuItem item=(MenuItem)event.widget;
				String protocolName=item.getText();
				if(monitors.containsKey(protocolName+" Monitor"))
				{
					tabFolder.setSelection(monitors.get(protocolName+" Monitor").tabItem);
				}
				else
				{
					monitors.put(protocolName+" Monitor",new KaginawaMonitor("netnotifier.notification",protocolName));
				}
			}
		};
		
		// populate the packet menu
		for(String protocolName : new String[]{"RawPacket","EthernetPacket","IPv4Packet","ARPPacket","TCPPacket","UDPPacket","ICMPPacket","ARPPacket","DNSPacket"})
		{
			MenuItem item=new MenuItem(packetMenu,SWT.PUSH);
			item.setText(protocolName);
			item.addListener(SWT.Selection,notificationMenuListener);
		}
		
		// populate the segment menu
		for(String protocolName : new String[]{"TCPSegment","TCPRead","TCPWrite","HTTPGet","HTTPPost","HTTPResponse"})
		{
			MenuItem item=new MenuItem(segmentMenu,SWT.PUSH);
			item.setText(protocolName);
			item.addListener(SWT.Selection,notificationMenuListener);
		}
	
		// populate the session menu
		for(String protocolName : new String[]{"TCPSession","HTTPSession"})
		{
			MenuItem item=new MenuItem(sessionMenu,SWT.PUSH);
			item.setText(protocolName);
			item.addListener(SWT.Selection,notificationMenuListener);
		}
		
		shell.setMenuBar(menuBar);
	}
	
	private static void generateTabFolder(Shell shell)
	{
		tabFolder = new CTabFolder(shell, SWT.CLOSE);
		tabFolder.addCTabFolder2Listener(new CTabFolder2Listener()
		{
			public void close(CTabFolderEvent event)
			{
				CTabItem item=(CTabItem)event.item;
				monitors.remove(item.getText());
				event.item.dispose();
			}

			public void maximize(CTabFolderEvent event){}
			public void minimize(CTabFolderEvent event){}
			public void restore(CTabFolderEvent event){}
			public void showList(CTabFolderEvent event){}
		});
		tabFolder.setUnselectedCloseVisible(true);
		tabFolder.setLayoutData(new GridData(GridData.FILL_BOTH));	
	}
}
